Hook up sysrq for xencons.
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Thu, 1 Sep 2005 10:38:57 +0000 (10:38 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Thu, 1 Sep 2005 10:38:57 +0000 (10:38 +0000)
Having sysrq is regularly handy.  Following in the tradition set by the
various consoles for virtual ppc stuff, the sysrq key is ^O.
Signed-off-by: Jeremy Katz <katzj@redhat.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
linux-2.6-xen-sparse/drivers/xen/console/console.c
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h

index 432f15594eeea71e9d21d991b680cf600384b4e8..f19dd485e3854e552d17480b6a4473d5c49f5360 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/bootmem.h>
+#include <linux/sysrq.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT;
 static int xc_num = -1;
 
+#ifdef CONFIG_MAGIC_SYSRQ
+static unsigned long sysrq_requested;
+extern int sysrq_enabled;
+#endif
+
 static int __init xencons_setup(char *str)
 {
     char *q;
@@ -296,7 +302,7 @@ static int xencons_priv_irq;
 static char x_char;
 
 /* Non-privileged receive callback. */
-static void xencons_rx(char *buf, unsigned len)
+static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
 {
     int           i;
     unsigned long flags;
@@ -304,8 +310,27 @@ static void xencons_rx(char *buf, unsigned len)
     spin_lock_irqsave(&xencons_lock, flags);
     if ( xencons_tty != NULL )
     {
-        for ( i = 0; i < len; i++ )
+        for ( i = 0; i < len; i++ ) {
+#ifdef CONFIG_MAGIC_SYSRQ
+            if (sysrq_enabled) {
+                if (buf[i] == '\x0f') { /* ^O */
+                    sysrq_requested = jiffies;
+                    continue; /* don't print the sysrq key */
+                } else if (sysrq_requested) {
+                    unsigned long sysrq_timeout = sysrq_requested + HZ*2;
+                    sysrq_requested = 0;
+                    /* if it's been less than a timeout, do the sysrq */
+                    if (time_before(jiffies, sysrq_timeout)) {
+                        spin_unlock_irqrestore(&xencons_lock, flags);
+                        handle_sysrq(buf[i], regs, xencons_tty);
+                        spin_lock_irqsave(&xencons_lock, flags);
+                        continue;
+                    }
+                }
+            }
+#endif
             tty_insert_flip_char(xencons_tty, buf[i], 0);
+        }
         tty_flip_buffer_push(xencons_tty);
     }
     spin_unlock_irqrestore(&xencons_lock, flags);
index 889a6a3ac1f17a437bed1b0efd9a2f49fc55cd98..2499d803521d31055f119cbb8d654c6dee57b455 100644 (file)
@@ -82,7 +82,7 @@ static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
        while (ring->cons < ring->prod) {
                if (xencons_receiver != NULL) {
                        xencons_receiver(ring->buf + XENCONS_IDX(ring->cons),
-                                        1);
+                                        1, regs);
                }
                ring->cons++;
        }
index be6e76cba8fd995a95f25261c3b7f8756aa16e5a..2b91fba968a4538e56dcd00ae4cd0b779770ee61 100644 (file)
@@ -7,7 +7,8 @@ asmlinkage int xprintk(const char *fmt, ...);
 int xencons_ring_init(void);
 int xencons_ring_send(const char *data, unsigned len);
 
-typedef void (xencons_receiver_func)(char *buf, unsigned len);
+typedef void (xencons_receiver_func)(char *buf, unsigned len, 
+                                     struct pt_regs *regs);
 void xencons_ring_register_receiver(xencons_receiver_func *f);
 
 #endif /* _XENCONS_RING_H */